![]() |
![]() |
|
Der Einsatz der Methoden ist ausgesprochen simpel. Legen Sie darauf Wert, die Zwischen-ablage nur dann auszuwerten, wenn sie ein bestimmtes Datenformat beherbergt, fragen Sie das mit einer der ContainsXxx-Methoden ab. Ist das Ergebnis positiv, also True, rufen Sie die Daten mit der entsprechenden GetXxx-Methode ab.
18.4.3 Mehrere Datenformate in der Zwischenablage
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Public Sub SetData(Object) |
| Public Sub SetData(Type, Object) |
| Public Sub SetData(String, Object) |
| Public Sub SetData(String, Boolean, Object) |
Dem String-Parameter können Sie auch in diesem Fall eine Konstante der Klasse DataFormats übergeben.
Der Einsatz der Methode ist sehr einfach. Zuerst erzeugen Sie ein DataObject-Objekt und rufen auf dessen Referenz die Methode SetData auf, der Sie jeweils Elemente unterschiedlichen Formats übergeben. Damit befindet sich der Inhalt natürlich noch nicht in der Zwischen-ablage, denn dazu ist der Aufruf der Methode SetDataObject der Clipboard-Klasse zuständig, der das DataObject-Objekt übergeben wird.
| Dim data As DataObject = New DataObject() |
| data.SetData(DataFormats.Text, "Irgendeine Zeichenfolge") |
| Clipboard.SetDataObject(data) |
Sollen mehrere unterschiedliche Formate der Zwischenablage übergeben werden, muss SetData mehrfach aufgerufen werden. Sehen wir uns dazu ein Beispiel an, bei dem der Zwischen-ablage sowohl eine Bitmap als auch eine Zeichenfolge übergeben wird.
| ' ---------------------------------------------------------- |
| ' Beispiel: ...\Kapitel 18\DataObjectDemo |
| ' ---------------------------------------------------------- |
| Public Class Form1 |
| Private myBitmap As Bitmap |
| Private Sub Form1_Load(...) Handles MyBase.Load |
| Dim width As Integer = PictureBox1.ClientSize.Width |
| Dim height As Integer = PictureBox1.ClientSize.Height |
| Dim data As DataObject = New DataObject() |
| ' Bitmap erzeugen |
| myBitmap = New Bitmap(width, height) |
| Dim g As Graphics = Graphics.FromImage(myBitmap) |
| g.FillRectangle(New SolidBrush(Color.White), _ |
| 0, 0, width, height) |
| g.DrawLine(New Pen(Color.Blue, 4), 0, 0, width, height) |
| g.DrawLine(New Pen(Color.Red, 4), width, 0, 0, height) |
| ' Bitmap in die Zwischenablage kopieren |
| data.SetData(DataFormats.Bitmap, myBitmap) |
| ' zusätzlichen Text in die Zwischenablage kopieren |
| data.SetData(DataFormats.Text, "Feuchtfröhliche Feier") |
| ' DataObject-Objekt der Zwischenablage übergeben |
| Clipboard.SetDataObject(data) |
| End Sub |
| Private Sub btnShowClipBoard_Click(...) _ |
| Handles btnShowClipBoard.Click |
| Dim dataObj As IDataObject = Clipboard.GetDataObject() |
| ' Bitmap aus der Zwischenablage in die Picturebox kopieren |
| If (dataObj.GetDataPresent(DataFormats.Bitmap)) Then |
| PictureBox1.Image = _ |
| dataObj.GetData(DataFormats.Bitmap) |
| End If |
| ' Text aus der Zwischenablage in die Textbox kopieren |
| If (dataObj.GetDataPresent(DataFormats.Text)) Then |
| TextBox1.Text = dataObj.GetData(DataFormats.Text) |
| End If |
| End Sub |
| End Class |
Im Konstruktor der Form wird nach der Initialisierungsroutine programmatisch eine Bitmap in weißer Hintergrundfarbe und mit zwei Diagonalen erzeugt. Die Bitmap wird dem DataObject-Objekt übergeben, zusätzlich auch noch eine Zeichenfolge. Zum Schluss wird das DataObject-Objekt in die Zwischenablage geschrieben.
Die Form enthält neben einer Schaltfläche eine Picturebox und eine Textbox. Wird auf die Schaltfläche geklickt, wird der Inhalt der Zwischenablage einer Typuntersuchung unterzogen mit dem Ergebnis, dass die Bitmap in der Picturebox angezeigt wird und die Zeichenfolge in der Textbox (siehe Abbildung 18.8).

Hier klicken, um das Bild zu Vergrößern
Abbildung 18.8 Ausgabe des Beispielprogramms »DataObjectDemo«
Schließen Sie die Anwendung, geht der Inhalt der Zwischenablage verloren. Wollen Sie, dass beispielsweise die Bitmap auch danach noch von einer anderen Anwendung wie MS Paint aus der Zwischenablage geholt werden kann, muss das DataObject-Object mit
| Clipboard.SetDataObject(data, True) |
der Zwischenablage übergeben werden.
Die Klasse DataFormats definiert eine Reihe von Formaten. Sie sind aber nicht ausschließlich an diese Liste gebunden, sondern können auch eigene Datentypen in die Zwischenablage kopieren. Dabei kommt die dreiparametrige Variante der Methode SetData zum Einsatz. Der erste Parameter empfängt den Namen des neuen Datenformats, der boolesche Parameter gibt Auskunft darüber, ob die Konvertierung in ein anderes Format zulässig ist, und dem dritten Parameter werden die zu kopierenden Daten übergeben.
Nehmen wir an, es wäre der Typ ClassA wie folgt definiert:
| <Serializable()> Class ClassA |
| Public Number As Integer |
| Public Name As String |
| End Class |
Beachten Sie, dass Typen, welche die Fähigkeit besitzen sollen, in die Zwischenablage kopiert zu werden, das Attribut Serializable aufweisen müssen.
Mit dem folgenden Code können wir ein Objekt des benutzerdefinierten Typs ClassA in die Zwischenablage kopieren:
| Dim obj As New ClassA |
| obj.Number = 5500 |
| obj.Name = "Pelztier" |
| Dim data As New DataObject |
| data.SetData("ClassA", True, obj) |
| Clipboard.SetDataObject(data, True) |
Dem SetDataObject-Aufruf übergeben wir True. Daher kann auch nach dem Beenden der aktuellen Anwendung eine andere Anwendung die Daten auswerten – vorausgesetzt, der Anwendung ist der Typ ClassA bekannt.
Die Daten aus der Zwischenablage zu lesen, ist sehr einfach:
| Dim dataObj As IDataObject = Clipboard.GetDataObject() |
| If (dataObj.GetDataPresent("ClassA")) Then |
| Dim obj1 As ClassA = dataObj.GetData("ClassA") |
| MessageBox.Show(obj1.Number.ToString() & obj1.Name) |
| End If |
Das Leeren der Zwischenablage erfolgt mit dem Aufruf der Methode Clear:
| Clipboard.Clear() |
Kommen wir nun zum Ausgangspunkt zurück, der dazu führte, dass wir uns mit der Programmierung der Zwischenablage beschäftigt haben. Wir wollten einer Textbox ein Kontextmenü bereitstellen, in dem die Menüelemente Ausschneiden, Kopieren und Einfügen implementiert sind. Dazu ergänzen wir das in Abschnitt 18.2.6 begonnene Beispielprogramm, in dem wir auch noch nicht die gleich lautenden Untermenüs von Bearbeiten codiert haben.
| ' --------------------------------------------------------- |
| ' Beispiel: ...\Kapitel 18\ContexMenuDemo |
| ' --------------------------------------------------------- |
| Public Class Form1 |
| Private Sub Form1_Load(...) Handles MyBase.Load |
| Clipboard.Clear() |
| End Sub |
| ... |
| End Class |
Der Load-Ereignishnadler ist um eine Anweisung ergänzt, welche die Zwischenablage beim Start der Anwendung leert. Das ist keine Notwendigkeit, sondern dient nur dazu, das Verhalten des Menüelements Einfügen besser verfolgen zu können.
Sehen wir uns nun den Ereignishandler an, der markierten Text aus einer Textbox in die Zwischenablage schreibt.
| Private Sub mnuKopieren_Click(...) Handles mnuKopieren.Click |
| Clipboard.SetText(CType(Me.ActiveControl, _ |
| TextBox).SelectedText) |
| End Sub |
Mit der Eigenschaft ActiveControl fragen wir das aktuell fokussierte Steuerelement ab, das in unserem Beispiel nur eine der beiden Textboxen sein kann. Den markierten Text schreiben wir in die Zwischenablage.
Nun folgt die Methode, um eine markierte Textpassage auszuschneiden.
| Private Sub mnuAusschneiden_Click(...) _ |
| Handles mnuAusschneiden.Click |
| Dim txt As TextBox = CType(Me.ActiveControl, TextBox) |
| Clipboard.SetText(txt.SelectedText) |
| ' Cursorposition merken |
| Dim cursorPosition As Integer = txt.SelectionStart |
| Me.Ausschneiden(txt) |
| ' Eingabecursor positionieren |
| txt.SelectionStart = cursorPosition |
| End Sub |
Üblicherweise bleibt nach dem Ausschneiden der Cursor an seiner Position stehen. Deshalb merken wir uns in der Variablen cursorPosition diese und setzen nach der Zeichenfolgemanipulation den Cursor wieder passend ein. Würden wir darauf verzichten, wäre der Cursor vor dem ersten Zeichen positioniert.
Das Ausschneiden des markierten Textes und das neuerliche Zusammensetzen der Restzeichenfolge erfolgt in der Methode Ausschneiden. Diese erwartet die Referenz auf die Textbox, aus der die markierte Teilzeichenfolge ausgeschnitten werden soll.
| ' Ausschneiden des markierten Texts |
| Private Sub Ausschneiden(ByVal txt As TextBox) |
| Dim iLength As Integer = txt.SelectionLength + _ |
| txt.SelectionStart |
| txt.Text = txt.Text.Substring(0, txt.SelectionStart) & _ |
| txt.Text.Substring(iLength, txt.Text.Length – iLength) |
| End Sub |
Das Einfügen eines Textes ist schon etwas aufwändiger. Wir müssen dabei zwei Dinge berücksichtigen:
| Ist kein Text in der Textbox markiert, in die der Inhalt der Zwischenablage geschrieben werden soll, wird die Position des Cursors als Einfügeposition bewertet. |
| Sollte in der Textbox Text markiert sein, muss dieser durch den Inhalt der Zwischenablage ersetzt werden. |
Nach dem Einfügen gilt es, die neue Zeichenfolge zu bilden und den Cursor an das Ende des eingefügten Textes zu setzen.
| Private Sub mnuEinfuegen_Click(...) Handles mnuEinfuegen.Click |
| Dim txt As TextBox = CType(Me.ActiveControl, TextBox) |
| ' Cursorposition merken |
| Dim cursorPosition As Integer = txt.SelectionStart |
| ' falls markierter Text durch den Inhalt der |
| ' Zwischenablage ersetzt werden soll |
| If (txt.SelectedText.Length > 0) Then |
| Me.Ausschneiden(txt) |
| End If |
| ' Teilstrings links und rechts des Cursors bestimmen |
| Dim strLinks As String = _ |
| txt.Text.Substring(0, cursorPosition) |
| Dim strRechts As String = _ |
| txt.Text.Substring(cursorPosition, _ |
| txt.Text.Length – cursorPosition) |
| ' Inhalt der Zwischenablage abrufen |
| Dim strClip As String = Clipboard.GetText() |
| ' neue Zeichenfolge zusammensetzen |
| txt.Text = strLinks + strClip + strRechts |
| ' Eingabecursor hinter dem eingefügten Text positionieren |
| txt.SelectionStart = cursorPosition + strClip.Length |
| End Sub |
Markierter Text wird mit dem Menüelement Löschen ausgeschnitten, aber nicht der Zwischenablage übergeben. Die Cursorposition ist anschließend zwischen den beiden verbleibenden Teilstrings. Für das Ausschneiden hatten wir weiter oben eine gleichnamige Methode bereitgestellt.
| Private Sub mnuLoeschen_Click(...) Handles mnuLoeschen.Click |
| Dim txt As TextBox = CType(Me.ActiveControl, TextBox) |
| ' Startposition des Cursors merken |
| Dim cursorPosition As Integer = txt.SelectionStart |
| Me.Ausschneiden(txt) |
| ' Cursor setzen |
| txt.SelectionStart = cursorPosition |
| End Sub |
Unabhängig davon, ob der Benutzer sich des Anwendungs- oder Kontextmenüs bedient, um den Inhalt einer Textbox zu verändern, die Funktionalitäten Ausschneiden, Kopieren, Löschen und Einfügen bleiben dieselben. Daher werden die Click-Ereignisse der Menüelemente des Kontextmenüs mit den entsprechenden Ereignishandlern des Anwendungsmenüs verknüpft.
Das Ereignis DropDownOpening wird ausgelöst, ehe das angeklickte Menüelement sein Untermenü öffnet. Wir nutzen dieses Ereignis des Menüpunktes Bearbeiten, um festzustellen, ob sich einfügbarer Text in der Zwischenablage befindet. Wenn nicht, kann der Menüpunkt Einfügen deaktiviert werden.
Ist in der aktiven Textbox kein Text markiert, gibt es nichts zu löschen, auszuschneiden oder in die Zwischenablage zu kopieren. Dann können die Menüpunkte Ausschneiden, Löschen und Kopieren deaktiviert angezeigt werden.
Diese Prüfungen vollzieht der Ereignishandler des DropDownOpening-Ereignisses.
| Private Sub mnuBearbeiten_DropDownOpening(...) _ |
| Handles mnuBearbeiten.DropDownOpening |
| Dim txt As TextBox = CType(Me.ActiveControl, TextBox) |
| ' Prüfen, ob sich in der Zwischenablage textuelle Daten befinden |
| If Not Clipboard.ContainsText() Then |
| mnuEinfuegen.Enabled = False |
| Else |
| mnuEinfuegen.Enabled = True |
| End If |
| ' Prüfen, ob Text in der aktiven Textbox markiert ist |
| If (txt.SelectedText = "") Then |
| mnuKopieren.Enabled = False |
| mnuAusschneiden.Enabled = False |
| mnuLoeschen.Enabled = False |
| Else |
| mnuKopieren.Enabled = True |
| mnuAusschneiden.Enabled = True |
| mnuLoeschen.Enabled = True |
| End If |
| End Sub |
Analog wird auch die Aktivierung der Menüelemente des Kontextmenüs gesteuert. Dazu dient uns das Ereignis Opening.
| Private Sub ContextMenuStrip1_Opening(...) _ |
| Handles ContextMenuStrip1.Opening |
| Dim txt As TextBox = CType(Me.ActiveControl, TextBox) |
| ' Prüfen, ob sich in der Zwischenablage textuelle Daten befinden |
| If Not Clipboard.ContainsText() Then |
| conEinfuegen.Enabled = False |
| Else |
| conEinfuegen.Enabled = True |
| End If |
| ' es ist kein Text in der aktiven Textbox markiert |
| If (txt.SelectedText = "") Then |
| conKopieren.Enabled = False |
| conAusschneiden.Enabled = False |
| conLoeschen.Enabled = False |
| Else |
| conKopieren.Enabled = True |
| conAusschneiden.Enabled = True |
| conLoeschen.Enabled = True |
| End If |
| End Sub |
Kommen wir jetzt zum letzten Schritt. Im Kontextmenü wird ebenfalls die Änderung der Hintergrundfarbe angeboten. Wir müssen die Methode ChangeColor, die auch diesen Menüelementen als Ereignishandler dient, so ergänzen, dass eine Änderung der Farbe auch vom entsprechenden Kontextmenüelement verzeichnet wird.
| ' Ereignishandler der Click-Ereignisse der Menüelemente, mit denen |
| ' die Hintergrundfarbe der Textboxen geändert werden kann |
| Private Sub ChangeColor(...) Handles mnuWeiß.Click, _ |
| mnuRot.Click, mnuGelb.Click, mnuBlau.Click, _ |
| conWeiß.Click, conRot.Click, conGelb.Click, _ |
| conBlau.Click |
| For Each temp As ToolStripMenuItem _ |
| In conHintergrundfarbe.DropDownItems |
| temp.Checked = False |
| Next |
| For Each temp As ToolStripMenuItem _ |
| In mnuHintergrundfarbe.DropDownItems |
| temp.Checked = False |
| Next |
| Select Case (sender.Text) |
| Case "Weiß" |
| txtOben.BackColor = Color.White |
| txtUnten.BackColor = Color.White |
| conWeiß.Checked = True |
| mnuWeiß.Checked = True |
| Case "Rot" |
| txtOben.BackColor = Color.Red |
| txtUnten.BackColor = Color.Red |
| conRot.Checked = True |
| mnuRot.Checked = True |
| ... |
| End Select |
| End Sub |
| << zurück |
|
||||||||||||||
|
||||||||||||||
|
||||||||||||||
|
||||||||||||||
Copyright © Galileo Press 2007
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken.
Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die
gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich
geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung,
Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.